import React, { useEffect } from "react";

import * as d3 from "d3";
import { VbpStatsByCadnI } from "../../../types";

interface PropsI {
  data: VbpStatsByCadnI[];
}

const GroupBarChartByCadn: React.FC<PropsI> = (props) => {
  const { data } = props;
  const refChart = React.useRef(null);

  useEffect(() => {
    if (refChart && refChart.current && data && data.length > 0) {
      const node = refChart.current;

      // 使用d3.rollup()汇总数据
      const aggregatedData = d3.rollup(
        data,
        (
          group // 对应每个分组的数据
        ) =>
          d3.sum(group, (d) => {
            return d.ratio;
          }),
        (d) => d.cadn, // cadn
        (d) => d.vbpClass // vbpClass
      );

      const vbpClasses = new Set(data.map((d) => d.vbpClass));
      // console.log(vbpClasses.size);
      // 设定svg元素所占面积
      var rectStep = 45;
      const width = 1280;
      const height = rectStep * aggregatedData.size * vbpClasses.size;
      // 设定四周边距
      const margin = { top: 50, right: 30, bottom: 30, left: 200 };

      d3.select(node).selectAll("svg").remove();
      var svg = d3
        .select(node)
        .append("svg")
        .attr("width", width)
        .attr("height", height)
        .attr("viewBox", [0, 0, width, height]) // 后续rect等图是相对viewBox计算的，viewBox可随svg绽放
        .attr("style", "max-width: 100%; height: auto;");
      // .attr("transform", `translate(${margin.left}, ${margin.top})`); // svg元素相对父节点元素位置

      const xScale = d3
        .scaleLinear()
        .domain([
          0,
          d3.max(aggregatedData, (D) => {
            // console.log(D);
            return d3.max(D[1], (d) => {
              // console.log(d);
              return d[1];
            });
          }) || 0,
        ])
        .range([0, width - margin.left - margin.right]);

      const yGroupScale = d3
        .scaleBand()
        .domain(new Set(data.map((d) => d.cadn)))
        .rangeRound([0, height - margin.top - margin.bottom])
        .paddingInner(0.3);

      // console.log(yGroupScale.bandwidth());

      // console.log(d3.schemeSpectral[3]); // 至少3种颜色
      // console.log(d3.schemeSpectral);
      const colorScale = d3
        .scaleOrdinal()
        .domain(vbpClasses)
        // .range(d3.schemeSpectral[vbpClasses.size]);
        .range(["green", "orange", "#335533", "blue"]);
      console.log(colorScale("中选"));

      const yScale = d3
        .scaleBand()
        .domain(vbpClasses)
        .rangeRound([0, yGroupScale.bandwidth()])
        .padding(0.1);

      // console.log(yScale.bandwidth());

      // console.log(new Set(data.map((d) => d.cadn)));
      // console.log(yScale("中选"));
      // console.log(yScale("原研"));

      // 添加 x 轴
      svg
        .append("g")
        .attr("transform", `translate(${margin.left},${margin.top})`)
        .call(d3.axisTop(xScale).tickSize(1));

      // 添加 y 轴
      svg
        .append("g")
        .attr("class", "yAxis")
        .attr("transform", `translate(${margin.left},${margin.top})`)
        .call(d3.axisLeft(yScale).tickSize(0))
        .selectAll(".domain")
        .remove();

      svg.selectAll(".yAxis").selectAll("text").remove();

      // 添加坐标轴标签
      svg
        .append("text")
        .attr("class", "x-label")
        .attr("text-anchor", "end")
        .attr("x", margin.left + (width - margin.left - margin.right) / 2) // 横坐标标签居中
        .attr("y", 20) // 位于 x 轴下方
        .text("比例");

      // console.log(margin.top + (height - margin.top - margin.bottom) / 2);

      svg
        .append("text")
        .attr("class", "y-label")
        .attr("text-anchor", "middle")
        .attr("transform", "rotate(-90)") // 旋转 90 度；旋转后x, y属性也受影响
        .attr("x", -(margin.top + (height - margin.top - margin.bottom) / 2)) // 横坐标标签居中
        .attr("y", 30) // 向上偏移
        .text("药品类别");

      // 画柱状图
      svg
        .append("g")
        .attr("transform", `translate(${margin.left},${margin.top})`) // 相对svg元素
        .selectAll()
        .data(aggregatedData)
        .join("g")
        .attr("transform", (D) => `translate(0, ${yGroupScale(D[0])})`) // 相对g元素
        .selectAll()
        // .data(([, d]) => d)  // 一种快捷的解构写法
        .data((D) => D[1])
        .join("rect")
        .attr("x", 0)
        .attr("y", (d) => yScale(d[0]) || 10)
        .attr("width", (d) => xScale(d[1]))
        .attr("height", (d) => yScale.bandwidth())
        .attr("fill", (d) => colorScale(d[0]) as string);

      // 添加标签;
      svg
        .selectAll(".groupLabel")
        .data(aggregatedData)
        .join("text")
        .attr("class", "groupLabel")
        .attr("transform", `translate(0,${margin.top})`) // 相对svg元素
        .attr("font-weight", "normal")
        .attr("font-size", 12)
        .attr("x", 60)
        .attr("y", (D) => yGroupScale(D[0])! + yGroupScale.bandwidth() / 2)
        .attr("dy", "0.35em")
        .text((D) => D[0]); // 画完分组标签

      // 添加
      svg
        .selectAll(".group")
        .data(aggregatedData)
        .join("g")
        .attr("class", "group")
        .attr(
          "transform",
          (D) => `translate(0, ${margin.top + yGroupScale(D[0])})`
        )
        .selectAll(".label")
        .data(([, d]) => d)
        .join("text")
        .attr("transform", `translate(${margin.left - 70}, 0)`) // 相对svg元素
        .attr("font-weight", "normal")
        .attr("font-size", 12)
        .attr("x", (d) => xScale(d[1]))
        .attr("y", (d) => {
          return yScale(d[0])! + yScale.bandwidth() / 2;
        })
        .attr("dy", "0.35em")
        .text((d) => {
          // console.log(d);
          return d[0] + " " + d[1].toFixed(2);
        });

      // 添加图例
      const legend = svg
        .selectAll(".legend")
        .data(colorScale.domain())
        .join("g")
        .attr("class", "legend")
        .attr("transform", (d, i) => `translate(0,${i * 20 + 20})`);

      legend
        .append("rect")
        .attr("x", 18)
        .attr("width", 18)
        .attr("height", 18)
        .style("fill", colorScale as any);

      legend
        .append("text")
        .attr("x", 76)
        .attr("y", 9)
        .attr("dy", ".35em")
        .style("text-anchor", "end")
        .text((d) => d);
    }
    // 清除副作用
    return () => {
      d3.select(refChart.current).selectAll("*").remove();
    };
  }, [data]);

  return (
    <div>
      <div ref={refChart}></div>
    </div>
  );
};

export default GroupBarChartByCadn;
